#!/bin/bash

# Script: CtyunOS 23.01 OpenSSL and OpenSSH Advanced Update Script (Source Compile)
# This script is adapted for CtyunOS 23.01, which is based on OpenEuler 22.03.
# Features:
#   1. Automatically update OpenSSL to the latest version (source compile, using Tencent Cloud mirror)
#   2. Update all system patches using DNF/YUM
#   3. Automatically update OpenSSH to the latest version (source compile, using Tencent Cloud mirror)
#   4. Change SSH port to a random port (20000-40000), ensure authentication settings, and configure firewall/SELinux
#   5. Display final OpenSSL, OpenSSH versions and SSH port
#   6. Self-delete script after successful execution

# --- ANSI Color Codes for Highlighting (Brighter Colors for Dark Background) ---
LIGHT_RED='\033[1;91m'    # Bright Red
LIGHT_GREEN='\033[1;92m'  # Bright Green
LIGHT_YELLOW='\033[1;93m' # Bright Yellow
LIGHT_BLUE='\033[1;94m'   # Bright Blue
NC='\033[0m'              # No Color

# --- Function: Determine Package Manager (DNF or YUM) ---
get_package_manager() {
    if command -v dnf &>/dev/null; then
        echo "dnf"
    elif command -v yum &>/dev/null; then
        echo "yum"
    else
        echo ""
    fi
}

PKG_MANAGER=$(get_package_manager)

# --- Function: Auto-confirm with delay ---
auto_confirm_with_delay() {
    local prompt_message="$1"
    local delay="$2"
    echo ""
    echo -e "${LIGHT_YELLOW}INFO:${NC} $prompt_message"
    echo -e "${LIGHT_YELLOW}INFO:${NC} Automatically continuing in $delay seconds..."
    for ((i=$delay; i>=1; i--)); do
        echo -n "$i "
        sleep 1
    done
    echo "Continuing execution."
    return 0 # Always confirms (yes)
}

# --- Security Warning and User Confirmation (with countdown) ---
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
echo -e "${LIGHT_RED}!! WARNING: This script will compile and install OpenSSL and OpenSSH from !!${NC}"
echo -e "${LIGHT_RED}!! source on CtyunOS 23.01 (based on OpenEuler 22.03).                    !!${NC}"
echo -e "${LIGHT_RED}!! This process carries high risks and may affect system stability or     !!${NC}"
echo -e "${LIGHT_RED}!! connectivity.                                                          !!${NC}"
echo -e "${LIGHT_RED}!! Ensure you are running this specific OS version.                       !!${NC}"
echo -e "${LIGHT_RED}!! BACKUP your system before proceeding!                                  !!${NC}"
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
# First confirmation uses a 3-second delay
auto_confirm_with_delay "Do you understand the above risks and wish to proceed with this script?" 3

# --- Check for root privileges ---
if [[ $EUID -ne 0 ]]; then
   echo -e "${LIGHT_RED}ERROR:${NC} This script must be run with root privileges."
   exit 1
fi

# --- Check for package manager ---
if [ -z "$PKG_MANAGER" ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Neither dnf nor yum found. Cannot proceed without a package manager."
    exit 1
else
    echo -e "${LIGHT_BLUE}INFO:${NC} Using package manager: $PKG_MANAGER"
fi

echo -e "${LIGHT_BLUE}INFO:${NC} Script execution started."
echo -e "${LIGHT_BLUE}INFO:${NC} Current time: $(date)"


# --- 1. Automatically Get Latest OpenSSL and OpenSSH Versions ---
echo ""
echo -e "### ${LIGHT_BLUE}STEP 1: Automatically Getting Latest OpenSSL and OpenSSH Versions${NC} ###"

# Automatically detect the latest stable OpenSSL 1.1.1 version from Tencent Cloud mirror
echo -e "${LIGHT_BLUE}INFO:${NC} Automatically detecting the latest stable OpenSSL 1.1.1 version from Tencent Cloud mirror..."
OPENSSL_SOURCE_MIRROR="https://mirrors.cloud.tencent.com/openssl/source/"
LATEST_OPENSSL_TARBALL=$(curl -s "$OPENSSL_SOURCE_MIRROR" | grep -oE 'openssl-1\.1\.1[a-z]?\.tar\.gz' | sort -V | tail -n1)

if [ -z "$LATEST_OPENSSL_TARBALL" ]; then
    echo -e "${LIGHT_YELLOW}WARNING:${NC} Failed to automatically detect the latest OpenSSL 1.1.1 version. Falling back to default: 1.1.1w"
    OPENSSL_VERSION="1.1.1w"
else
    OPENSSL_VERSION=$(echo "$LATEST_OPENSSL_TARBALL" | sed -E 's/openssl-(.*)\.tar\.gz/\1/')
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} Detected latest OpenSSL version: $OPENSSL_VERSION"
fi

# Automatically detect the latest stable OpenSSH portable version from Tencent Cloud mirror
echo -e "${LIGHT_BLUE}INFO:${NC} Automatically detecting the latest stable OpenSSH portable version from Tencent Cloud mirror..."
OPENSSH_MIRROR_URL="https://mirrors.cloud.tencent.com/OpenBSD/OpenSSH/portable/"
LATEST_OPENSSH_TARBALL=$(curl -s "$OPENSSH_MIRROR_URL" | grep -oE 'openssh-[0-9]+\.[0-9]+p[0-9]+\.tar\.gz' | sort -V | tail -n1)

if [ -z "$LATEST_OPENSSH_TARBALL" ]; then
    echo -e "${LIGHT_YELLOW}WARNING:${NC} Failed to automatically detect the latest OpenSSH version. Falling back to default: 10.0p1"
    SSH_VERSION="10.0p1" # Fallback updated to a reasonable recent version
else
    SSH_VERSION=$(echo "$LATEST_OPENSSH_TARBALL" | sed -E 's/openssh-(.*)\.tar\.gz/\1/')
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} Detected latest OpenSSH version: $SSH_VERSION"
fi

echo -e "${LIGHT_BLUE}INFO:${NC} Automatically detected OpenSSL version: $OPENSSL_VERSION"
echo -e "${LIGHT_BLUE}INFO:${NC} Automatically detected OpenSSH version: $SSH_VERSION"

# --- 2. Update System Patches to the Latest Version (using DNF/YUM) ---
echo ""
echo -e "### ${LIGHT_BLUE}STEP 2: Comprehensively updating system patches${NC} ###"
echo -e "${LIGHT_BLUE}INFO:${NC} This will update all installed system packages to their latest available versions using $PKG_MANAGER. This process may take some time..."
$PKG_MANAGER update -y
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_YELLOW}WARNING:${NC} Some errors might have occurred during system patch update. Please check the $PKG_MANAGER output above."
else
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} System patches successfully updated."
fi


# --- 3. Update OpenSSL to Specific Version (Source Compile) ---
echo ""
echo -e "### ${LIGHT_BLUE}STEP 3: Updating OpenSSL (Source Compile)${NC} ###"
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
echo -e "${LIGHT_RED}!! WARNING: Compiling OpenSSL from source carries high risks and may affect !!${NC}"
echo -e "${LIGHT_RED}!! system stability.                                                      !!${NC}"
echo -e "${LIGHT_RED}!! Always back up critical files and proceed with caution!                !!${NC}"
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
echo ""

OPENSSL_TARBALL="openssl-${OPENSSL_VERSION}.tar.gz"
# OpenSSL source download URL (using Tencent Cloud mirror)
OPENSSL_DOWNLOAD_URL="https://mirrors.cloud.tencent.com/openssl/source/${OPENSSL_TARBALL}"
OPENSSL_BUILD_DIR="/usr/local/src/openssl_build"
OPENSSL_INSTALL_DIR="/usr/local/openssl" # OpenSSL installation path to avoid conflict with system default

auto_confirm_with_delay "Do you need to compile and install OpenSSL ${OPENSSL_VERSION}?" 6
# Proceed with compile and install logic as auto_confirm_with_delay always returns 0.
echo -e "${LIGHT_BLUE}INFO:${NC} Installing OpenSSL compilation dependencies (perl, zlib-devel)..."
# OpenEuler uses dnf for these, so use PKG_MANAGER
$PKG_MANAGER install -y perl zlib-devel
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Failed to install perl or zlib-devel. Please check $PKG_MANAGER output."
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Dependencies installed."

mkdir -p "$OPENSSL_BUILD_DIR"
cd "$OPENSSL_BUILD_DIR" || { echo -e "${LIGHT_RED}ERROR:${NC} Cannot enter $OPENSSL_BUILD_DIR directory."; exit 1; }

echo -e "${LIGHT_BLUE}INFO:${NC} Downloading OpenSSL source: ${OPENSSL_DOWNLOAD_URL} (using Tencent Cloud mirror)..."
if command -v wget &>/dev/null; then
    wget "$OPENSSL_DOWNLOAD_URL"
elif command -v curl &>/dev/null; then
    curl -L -O "$OPENSSL_DOWNLOAD_URL"
fi

if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSL source download failed. Please check version number or network connection."
    rm -rf "$OPENSSL_BUILD_DIR"
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSL source downloaded."

echo -e "${LIGHT_BLUE}INFO:${NC} Extracting source package..."
tar -xzf "$OPENSSL_TARBALL"
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Failed to extract OpenSSL source package."
    rm -rf "$OPENSSL_BUILD_DIR"
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Source package extracted."

# Dynamically get the extracted directory name for OpenSSL
OPENSSL_SRC_DIR=$(tar -tf "$OPENSSL_TARBALL" | head -1 | cut -f1 -d"/")
if [ -z "$OPENSSL_SRC_DIR" ] || [ ! -d "$OPENSSL_BUILD_DIR/$OPENSSL_SRC_DIR" ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Could not find the extracted OpenSSL source directory. Expected something like 'openssl-${OPENSSL_VERSION}' but got '$OPENSSL_SRC_DIR'."
    exit 1
fi

cd "$OPENSSL_BUILD_DIR/$OPENSSL_SRC_DIR" || { echo -e "${LIGHT_RED}ERROR:${NC} Cannot enter $OPENSSL_BUILD_DIR/$OPENSSL_SRC_DIR directory."; exit 1; }


echo -e "${LIGHT_BLUE}INFO:${NC} Configuring, compiling, and installing OpenSSL..."
# --prefix specifies installation path, shared compiles shared libraries, zlib enables zlib compression support
./config --prefix="$OPENSSL_INSTALL_DIR" shared zlib
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSL configuration failed. Please check output."
    echo -e "${LIGHT_RED}ERROR:${NC} Please manually check $OPENSSL_BUILD_DIR/$OPENSSL_SRC_DIR/config.log for detailed errors."
    exit 1
fi

make
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSL compilation failed. Please check output."
    exit 1
fi

make install
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSL installation failed. Please check output."
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSL compiled and installed to $OPENSSL_INSTALL_DIR."

echo -e "${LIGHT_BLUE}INFO:${NC} Configuring dynamic linker to find the new OpenSSL libraries..."
# Add new OpenSSL library path to system dynamic linker configuration
echo "$OPENSSL_INSTALL_DIR/lib" > /etc/ld.so.conf.d/openssl-local.conf
ldconfig # Refresh dynamic linker cache
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Dynamic linker configured."

# Clean up build files
echo -e "${LIGHT_BLUE}INFO:${NC} Cleaning OpenSSL compilation files..."
rm -rf "$OPENSSL_BUILD_DIR"
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Cleanup complete."
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSL ${OPENSSL_VERSION} successfully installed and configured."


# --- 4. Update OpenSSH to Latest Version (Source Compile) ---
echo ""
echo -e "### ${LIGHT_BLUE}STEP 4: Updating OpenSSH (Source Compile)${NC} ###"
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
echo -e "${LIGHT_RED}!! WARNING: Compiling OpenSSH from source carries high risks and may cause  !!${NC}"
echo -e "${LIGHT_RED}!! SSH service to fail, leading to loss of remote access.                   !!${NC}"
echo -e "${LIGHT_RED}!! Always back up critical files and proceed with caution!                  !!${NC}"
echo -e "${LIGHT_RED}!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!${NC}"
echo ""

current_ssh_version_full=$(ssh -V 2>&1)
echo -e "${LIGHT_BLUE}INFO:${NC} Current OpenSSH version: $current_ssh_version_full"

auto_confirm_with_delay "Do you need to compile and install OpenSSH ${SSH_VERSION}?" 6
# Proceed with compile and install logic as auto_confirm_with_delay always returns 0.
# Check if wget or curl is installed
if ! command -v wget &>/dev/null && ! command -v curl &>/dev/null; then
    echo -e "${LIGHT_RED}ERROR:${NC} Neither wget nor curl command found, cannot download OpenSSH source. Please install one of them manually."
    exit 1
fi

# Install compilation dependencies (gcc, make, zlib-devel, pam-devel, libXt-devel)
echo -e "${LIGHT_BLUE}INFO:${NC} Installing OpenSSH compilation dependencies..."
# OpenEuler uses dnf for these
$PKG_MANAGER install -y gcc make zlib-devel pam-devel libXt-devel
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Failed to install OpenSSH compilation dependencies. Please check $PKG_MANAGER output."
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Dependencies installed."

# Create working directory
BUILD_DIR="/usr/local/src/openssh_build"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR" || { echo -e "${LIGHT_RED}ERROR:${NC} Cannot enter $BUILD_DIR directory."; exit 1; }

# OpenSSH source download URL (using Tencent Cloud mirror)
OPENSSH_TARBALL="openssh-${SSH_VERSION}.tar.gz"
OPENSSH_DOWNLOAD_URL="https://mirrors.cloud.tencent.com/OpenBSD/OpenSSH/portable/${OPENSSH_TARBALL}"

echo -e "${LIGHT_BLUE}INFO:${NC} Downloading OpenSSH source: ${OPENSSH_DOWNLOAD_URL} (using Tencent Cloud mirror)..."
if command -v wget &>/dev/null; then
    wget "$OPENSSH_DOWNLOAD_URL"
elif command -v curl &>/dev/null; then
    curl -L -O "$OPENSSH_DOWNLOAD_URL"
fi

if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSH source download failed. Please check version number or network connection."
    rm -rf "$BUILD_DIR"
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSH source downloaded."

echo -e "${LIGHT_BLUE}INFO:${NC} Extracting source package..."
tar -xzf "$OPENSSH_TARBALL"
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Failed to extract OpenSSH source package."
    rm -rf "$BUILD_DIR"
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Source package extracted."

# Dynamically get the extracted directory name for OpenSSH
OPENSSH_SRC_DIR=$(tar -tf "$OPENSSH_TARBALL" | head -1 | cut -f1 -d"/")
if [ -z "$OPENSSH_SRC_DIR" ] || [ ! -d "$BUILD_DIR/$OPENSSH_SRC_DIR" ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Could not find the extracted OpenSSH source directory. Expected something like 'openssh-${SSH_VERSION}' but got '$OPENSSH_SRC_DIR'."
    exit 1
fi

cd "$BUILD_DIR/$OPENSSH_SRC_DIR" || { echo -e "${LIGHT_RED}ERROR:${NC} Cannot enter $BUILD_DIR/$OPENSSH_SRC_DIR directory."; exit 1; }

# Back up existing OpenSSH configuration and host keys (backup before port modification to allow rollback in case of compilation failure)
SSH_BACKUP_DIR="/etc/ssh_backup_$(date +%Y%m%d%H%M%S)"
echo -e "${LIGHT_BLUE}INFO:${NC} Backing up existing OpenSSH configuration files and host keys to $SSH_BACKUP_DIR ..."
mkdir -p "$SSH_BACKUP_DIR"
cp -a /etc/ssh/sshd_config "$SSH_BACKUP_DIR/" 2>/dev/null
cp -a /etc/ssh/ssh_config "$SSH_BACKUP_DIR/" 2>/dev/null
cp -a /etc/ssh/ssh_host_* "$SSH_BACKUP_DIR/" 2>/dev/null
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSH configuration and keys backed up."

# Stop and disable old SSH service
echo -e "${LIGHT_BLUE}INFO:${NC} Stopping and disabling old OpenSSH service..."
systemctl stop sshd
systemctl disable sshd
echo -e "${LIGHT_GREEN}SUCCESS:${NC} Old service stopped and disabled."

# Compile and install
echo -e "${LIGHT_BLUE}INFO:${NC} Configuring, compiling, and installing OpenSSH..."
# Set environment variables to ensure OpenSSH compilation can find the newly installed OpenSSL libraries and header files
export CPPFLAGS="-I$OPENSSL_INSTALL_DIR/include"
export LDFLAGS="-L$OPENSSL_INSTALL_DIR/lib"

# Added --without-openssl-header-check to bypass header/library mismatch check
./configure \
    --prefix=/usr \
    --sysconfdir=/etc/ssh \
    --with-pam \
    --with-ssl-dir="$OPENSSL_INSTALL_DIR" \
    --with-privsep-path=/var/lib/sshd \
    --with-xauth=/usr/bin/xauth \
    --with-md5-passwords \
    --with-libs=-ldl \
    --without-openssl-header-check # FIX: Added to bypass header/library mismatch error
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSH configuration failed. Please check output."
    echo -e "${LIGHT_RED}ERROR:${NC} Please manually check $BUILD_DIR/$OPENSSH_SRC_DIR/config.log for detailed errors."
    exit 1
fi

make
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSH compilation failed. Please check output."
    exit 1
fi

make install
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} OpenSSH installation failed. Please check output."
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} OpenSSH compiled and installed."

# Copy new sshd_config example file and prompt user to merge
# Prioritize using the newly compiled default configuration, then proceed with subsequent port and authentication modifications
if [ -f "$BUILD_DIR/$OPENSSH_SRC_DIR/sshd_config" ]; then
    mv /etc/ssh/sshd_config /etc/ssh/sshd_config.old_$(date +%Y%m%d%H%M%S)_pre_new_install
    cp "$BUILD_DIR/$OPENSSH_SRC_DIR/sshd_config" /etc/ssh/sshd_config
    chmod 600 /etc/ssh/sshd_config
    echo -e "${LIGHT_BLUE}INFO:${NC} New sshd_config example file installed to /etc/ssh/sshd_config."
else
    echo -e "${LIGHT_YELLOW}WARNING:${NC} New compiled sshd_config example file not found. Please manually check if OpenSSH installation is complete."
fi

# Copy new ssh_config example file
if [ -f "$BUILD_DIR/$OPENSSH_SRC_DIR/ssh_config" ]; then
    mv /etc/ssh/ssh_config /etc/ssh/ssh_config.old_$(date +%Y%m%d%H%M%S)_pre_new_install
    cp "$BUILD_DIR/$OPENSSH_SRC_DIR/ssh_config" /etc/ssh/ssh_config
    chmod 644 /etc/ssh/ssh_config
    echo -e "${LIGHT_BLUE}INFO:${NC} New ssh_config example file installed to /etc/ssh/ssh_config."
else
    echo -e "${LIGHT_YELLOW}WARNING:${NC} New compiled ssh_config example file not found. Please manually check if OpenSSH installation is complete."
fi


# Ensure host keys exist, generate if not present
if [ ! -f /etc/ssh/ssh_host_rsa_key ]; then
    echo -e "${LIGHT_BLUE}INFO:${NC} Generating SSH host keys..."
    ssh-keygen -A
else
    echo -e "${LIGHT_BLUE}INFO:${NC} SSH host keys already exist, skipping generation."
fi

# Register new sshd service (if needed, usually handled by make install)
if [ -f "$BUILD_DIR/$OPENSSH_SRC_DIR/contrib/sshd.pam" ]; then
    cp "$BUILD_DIR/$OPENSSH_SRC_DIR/contrib/sshd.pam" /etc/pam.d/sshd
    echo -e "${LIGHT_BLUE}INFO:${NC} New PAM configuration copied to /etc/pam.d/sshd."
else
    echo -e "${LIGHT_YELLOW}WARNING:${NC} New PAM configuration file 'sshd.pam' not found. Please ensure /etc/pam.d/sshd is correctly configured."
fi

# Ensure systemd service file exists and is enabled
if [ ! -f /usr/lib/systemd/system/sshd.service ]; then
    echo -e "${LIGHT_YELLOW}WARNING:${NC} systemd sshd.service file not found. Attempting to copy from source directory."
    if [ -f "$BUILD_DIR/$OPENSSH_SRC_DIR/contrib/sshd.service" ]; then
        cp "$BUILD_DIR/$OPENSSH_SRC_DIR/contrib/sshd.service" /usr/lib/systemd/system/sshd.service
        systemctl daemon-reload
        echo -e "${LIGHT_GREEN}SUCCESS:${NC} sshd.service file copied and reloaded."
    else
        echo -e "${LIGHT_RED}ERROR:${NC} Could not find sshd.service file. Please manually create or fix systemd service."
        echo -e "${LIGHT_RED}ERROR:${NC} You may need to manually configure systemd to manage the new sshd service."
        echo -e "${LIGHT_RED}ERROR:${NC} Please refer to OpenSSH official documentation or OpenEuler/CtyunOS systemd configuration guide."
        exit 1
    fi
fi

echo -e "${LIGHT_BLUE}INFO:${NC} Testing new sshd configuration..."
/usr/sbin/sshd -t
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} New sshd configuration test failed! Please check for errors in /etc/ssh/sshd_config file."
    echo -e "${LIGHT_RED}ERROR:${NC} Do NOT attempt to start SSH service before fixing configuration issues, otherwise you might lose connectivity!"
    exit 1
else
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} sshd configuration test successful."
fi

# Note: SSH service is not started immediately here; it will be started after port modification
echo -e "${LIGHT_BLUE}INFO:${NC} OpenSSH compilation and installation complete, service not started yet, will start after port modification."


# --- 5. Modify SSH Port to Random Port (20000-40000) and Configure Firewall/SELinux ---
echo ""
echo -e "### ${LIGHT_BLUE}STEP 5: Modifying SSH Port and Configuring Firewall/SELinux${NC} ###"

NEW_SSH_PORT=$(($RANDOM % 20001 + 20000)) # Generate a random port between 20000 and 40000
echo -e "${LIGHT_BLUE}INFO:${NC} Changing SSH port to a random port: $NEW_SSH_PORT"

# Back up current sshd_config just in case (another backup before modification)
cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak_port_auth_$(date +%Y%m%d%H%M%S)

echo -e "${LIGHT_BLUE}INFO:${NC} Modifying /etc/ssh/sshd_config file..."
# 1. Delete all existing Port lines, then add the new random port
sed -i '/^Port /d' /etc/ssh/sshd_config
echo "Port $NEW_SSH_PORT" >> /etc/ssh/sshd_config

# 2. Ensure PermitRootLogin is set to yes (convenient for initial testing, you can modify it later as needed after successful connection)
# Check if PermitRootLogin line exists, replace if it does, otherwise add
if grep -qE "^\s*PermitRootLogin\s" /etc/ssh/sshd_config; then
    sed -i 's/^\s*PermitRootLogin\s.*/PermitRootLogin yes/' /etc/ssh/sshd_config
else
    echo "PermitRootLogin yes" >> /etc/ssh/sshd_config
fi

# 3. Ensure PasswordAuthentication is set to yes (convenient for initial testing, you can modify it later as needed after successful connection)
# Check if PasswordAuthentication line exists, replace if it does, otherwise add
if grep -qE "^\s*PasswordAuthentication\s" /etc/ssh/sshd_config; then
    sed -i 's/^\s*PasswordAuthentication\s.*/PasswordAuthentication yes/' /etc/ssh/sshd_config
else
    echo "PasswordAuthentication yes" >> /etc/ssh/sshd_config
fi

echo -e "${LIGHT_GREEN}SUCCESS:${NC} sshd_config file modification complete."

# Configure firewall
echo -e "${LIGHT_BLUE}INFO:${NC} Configuring firewall to allow new SSH port $NEW_SSH_PORT..."
if command -v firewall-cmd &>/dev/null; then
    # Use firewalld
    firewall-cmd --zone=public --permanent --add-port=${NEW_SSH_PORT}/tcp
    firewall-cmd --reload
    if [ $? -eq 0 ]; then
        echo -e "${LIGHT_GREEN}SUCCESS:${NC} Firewalld updated and reloaded."
    else
        echo -e "${LIGHT_YELLOW}WARNING:${NC} Firewalld configuration failed. Please manually check firewall settings."
    fi
elif command -v iptables &>/dev/null; then
    # Use iptables (OpenEuler defaults to firewalld, iptables is a fallback)
    iptables -I INPUT -p tcp --dport ${NEW_SSH_PORT} -j ACCEPT
    service iptables save
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} Iptables updated."
else
    echo -e "${LIGHT_YELLOW}WARNING:${NC} Neither firewalld nor iptables command found. Please manually configure firewall to allow new port $NEW_SSH_PORT."
fi

# Configure SELinux
echo -e "${LIGHT_BLUE}INFO:${NC} Configuring SELinux to allow new SSH port $NEW_SSH_PORT..."
if command -v semanage &>/dev/null; then
    # Check if port already exists with ssh_port_t type, if so, delete and re-add to avoid error
    if semanage port -l | grep -q "^ssh_port_t.*tcp.*${NEW_SSH_PORT}\b"; then
        echo -e "${LIGHT_YELLOW}WARNING:${NC} SELinux port ${NEW_SSH_PORT} (ssh_port_t) already exists, attempting to delete old rule and re-add."
        semanage port -d -t ssh_port_t -p tcp ${NEW_SSH_PORT}
    fi
    semanage port -a -t ssh_port_t -p tcp ${NEW_SSH_PORT}
    if [ $? -eq 0 ]; then
        echo -e "${LIGHT_GREEN}SUCCESS:${NC} SELinux port context added."
    else
        echo -e "${LIGHT_YELLOW}WARNING:${NC} SELinux port context addition failed. If SELinux is in enforcing mode, manual configuration might be needed."
        echo -e "${LIGHT_YELLOW}WARNING:${NC} Try using 'semanage port -a -t ssh_port_t -p tcp ${NEW_SSH_PORT}' or set SELinux to permissive mode ('setenforce 0')."
    fi
else
    echo -e "${LIGHT_YELLOW}WARNING:${NC} semanage command not found. If SELinux is in enforcing mode, manual configuration or disabling SELinux might be needed."
    echo -e "${LIGHT_YELLOW}WARNING:${NC} If SELinux blocks connections, check 'audit.log' (located at /var/log/audit/)."
fi


# Start and enable new OpenSSH service (after all configurations are complete)
echo -e "${LIGHT_BLUE}INFO:${NC} Testing new sshd configuration..."
/usr/sbin/sshd -t
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} New sshd configuration test failed! Please check for errors in /etc/ssh/sshd_config file."
    echo -e "${LIGHT_RED}ERROR:${NC} Do NOT attempt to start SSH service before fixing configuration issues, otherwise you might lose connectivity!"
    exit 1
else
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} sshd configuration test successful."
fi

echo -e "${LIGHT_BLUE}INFO:${NC} Starting and enabling new OpenSSH service..."
systemctl enable sshd
systemctl start sshd
if [ $? -ne 0 ]; then
    echo -e "${LIGHT_RED}ERROR:${NC} Failed to start new OpenSSH service. Please check logs (journalctl -xe) for details."
    echo -e "${LIGHT_RED}ERROR:${NC} You may need to manually restore the old SSH service or troubleshoot."
    exit 1
fi
echo -e "${LIGHT_GREEN}SUCCESS:${NC} New OpenSSH service started and enabled."


# --- 6. Final Status Report ---
echo ""
echo -e "------------------------------------------------------------------------"
echo -e "${LIGHT_BLUE}INFO:${NC} Script execution complete."
echo -e "${LIGHT_YELLOW}IMPORTANT:${NC} This script updated OpenSSL and OpenSSH on CtyunOS 23.01 (based on OpenEuler 22.03)."
echo -e "${LIGHT_YELLOW}IMPORTANT:${NC} System base packages were NOT updated by this script. Always ensure your system is up-to-date and secure."
echo -e "------------------------------------------------------------------------"
echo ""

echo -e "--- ${LIGHT_BLUE}Final Software Version Report${NC} ---"
# Check OpenSSL version, prioritize compiled path, otherwise system path
echo -e "${LIGHT_BLUE}INFO:${NC} OpenSSL Version: $(/usr/local/openssl/bin/openssl version 2>/dev/null || openssl version 2>/dev/null || echo "Unknown")"
# Check OpenSSH version, ensure only the first line is output
echo -e "${LIGHT_BLUE}INFO:${NC} OpenSSH Version: $(/usr/bin/ssh -V 2>&1 | head -n 1 || echo "Unknown")"

# Try to get current listening port from sshd_config, if not found, try from netstat/ss commands
CURRENT_LISTEN_PORT=$(grep -E '^\s*Port\s' /etc/ssh/sshd_config | awk '{print $2}' | head -n 1)
if [ -z "$CURRENT_LISTEN_PORT" ]; then
    CURRENT_LISTEN_PORT=$(ss -tuln | grep sshd | grep -oP '(?<=:)\d+' | head -n 1)
    if [ -z "$CURRENT_LISTEN_PORT" ]; then
        CURRENT_LISTEN_PORT="Unknown (Please verify with 'ss -tuln | grep sshd')"
    fi
fi
echo -e "${LIGHT_BLUE}INFO:${NC} Current SSH Listening Port: $CURRENT_LISTEN_PORT"
echo -e "------------------------------"

# Note: needs-restarting is generally for package manager updates. For source compiles, a reboot is always recommended.
echo -e "${LIGHT_YELLOW}WARNING:${NC} A system reboot is highly recommended to ensure all new OpenSSL/OpenSSH components are fully active."
auto_confirm_with_delay "Do you want to reboot the system now?" 6
echo -e "${LIGHT_BLUE}INFO:${NC} Rebooting system..."
reboot

# --- Self-delete the script ---
SCRIPT_PATH="$0"
if [ -f "$SCRIPT_PATH" ]; then
    echo -e "${LIGHT_YELLOW}INFO:${NC} Deleting self-script: $SCRIPT_PATH"
    rm -- "$SCRIPT_PATH"
    echo -e "${LIGHT_GREEN}SUCCESS:${NC} Script deleted successfully."
else
    echo -e "${LIGHT_RED}ERROR:${NC} Could not find script at $SCRIPT_PATH to delete."
fi

exit 0
